﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
///  @brief 控制器类，作为游戏逻辑的核心管理组件。
/// </summary>
public class Ctrl : MonoBehaviour
{
    /**
     * @brief 模型管理器的引用，通过标签"Model"在游戏对象中查找并获取。
     *        此字段在Inspector面板中隐藏，因为它是由代码自动赋值的。
     */
    [HideInInspector]
    public Model model;

    /**
     * @brief 视图管理器的引用，通过标签"View"在游戏对象中查找并获取。
     *        此字段在Inspector面板中隐藏，因为它是由代码自动赋值的。
     */
    [HideInInspector]
    public View view;

    /**
     * @brief 摄像机管理器的引用，通过GetComponent在当前游戏对象或其子对象中查找并获取。
     *        此字段在Inspector面板中隐藏，因为它是由代码自动赋值的。
     */
    [HideInInspector]
    public CameraManager cameraManager;

    /**
     * @brief 游戏管理器的引用，通过GetComponent在当前游戏对象或其子对象中查找并获取。
     *        此字段在Inspector面板中隐藏，因为它是由代码自动赋值的。
     */
    [HideInInspector]
    public GameManager gameManager;

    /**
     * @brief 音频管理器的引用，通过GetComponent在当前游戏对象或其子对象中查找并获取。
     *        此字段在Inspector面板中隐藏，因为它是由代码自动赋值的。
     */
    [HideInInspector]
    public AudioManager audioManager;

    /**
     * @brief 有限状态机（Finite State Machine）系统的实例。
     */
    private FSMSystem fsm;

    /**
     * @brief Awake方法，在对象被实例化时自动调用。
     *        用于初始化各个管理器、视图和状态机的引用。
     */
    private void Awake()
    {
        Debug.Log("[Ctrl] Initializing controller components...");
        model = GameObject.FindGameObjectWithTag("Model").GetComponent<Model>();
        view = GameObject.FindGameObjectWithTag("View").GetComponent<View>();
        cameraManager = GetComponent<CameraManager>();
        gameManager = GetComponent<GameManager>();
        audioManager = GetComponent<AudioManager>();
        Debug.Log("[Ctrl] Controller initialization completed");
    }

    /**
     * @brief Start方法，在对象首次启用时自动调用（通常在Awake之后）。
     *        用于构建和初始化有限状态机。
     */
    private void Start()
    {
        Debug.Log("[Ctrl] Starting controller initialization");
        MakeFSM();
    }

    /**
     * @brief Update方法，每帧调用一次。
     *        当前为空实现，但保留此方法以便后续添加游戏逻辑。
     */
    void Update()
    {
        // 空实现，保留以备后用
    }

    /**
     * @brief 构建和初始化有限状态机的方法。
     *        遍历当前游戏对象及其子对象中的所有FSMState组件，并将它们添加到状态机系统中。
     *        然后，查找并设置初始状态。
     */
    void MakeFSM()
    {
        Debug.Log("[Ctrl] Creating Finite State Machine...");
        fsm = new FSMSystem();
        FSMState[] states = GetComponentsInChildren<FSMState>();
        foreach (FSMState state in states)
        {
            Debug.Log($"[Ctrl] Adding state to FSM: {state.GetType().Name}");
            fsm.AddState(state, this);
        }
        MenuState s = GetComponentInChildren<MenuState>();
        Debug.Log("[Ctrl] Setting initial state to MenuState");
        fsm.SetCurrentState(s);
        Debug.Log("[Ctrl] FSM initialization completed");
    }
}